Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(decorators): check for own metadata in command/query handler #1181

Merged

Conversation

simur407
Copy link

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Other... Please describe:

What is the current behavior?

When there is two commands/queries that one inherits from the other and both of them have registered handlers, then metadata for them is defined only for parent and not for child. This causes the same ID to be generated for both commands/queries, sometimes resulting in wrong handler picking up the message.

Take a look at this example:

class ParentCommand {
  constructor(public readonly foo: string) {}
}

class ChildCommand extends ParentCommand {}

@CommandHandler(ParentCommand)
class ParentCommandHandler implements ICommandHandler<ParentCommand> {
  // ...
}

@CommandHandler(ChildCommand)
class ChildCommandHandler implements ICommandHandler<ChildCommand> {
  // ...
}

Snippet of previous implementation:

if (!Reflect.hasMetadata(COMMAND_METADATA, command)) {
  Reflect.defineMetadata(COMMAND_METADATA, { id: v4() }, command);
}

Now following previous behavior ParentCommandHandler would define metadata for ParentCommand with new ID, Then when checking ChildCommand it would check hasMetadata which will check for metadata not only for given class, but all it's parents. That would result in leaving the same ID both for ParentCommand and ChildCommand. The same applies for queries.
It would sometimes cause wrong handler to pick up wrong message.

Worth noting is that event-handler.decorator uses hasOwnMetadata making a distinction between parent and child.

What is the new behavior?

Now only own metadata will be checked.

Does this PR introduce a breaking change?

  • Yes
  • No

Actually it's debatable. Behavior of command and query handlers will be changing, meaning it will not pickup wrong commands by mistake, but it was not intended, I assume.

Other information

When there is two commands/queries that one inherits from the other and both of them have registered handlers, then metadata for them is defined only for parent and not for child. This causes the same ID to be generated for both commands/queries, sometimes resulting in wrong handler picking up the message.
@jmcdo29
Copy link
Member

jmcdo29 commented Dec 5, 2022

@kamilmysliwiec could you take a look at this? Seems like a pretty solid fix for what's going on.

@kamilmysliwiec kamilmysliwiec merged commit 14a12d4 into nestjs:master Feb 9, 2023
@kamilmysliwiec
Copy link
Member

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants